EC2のChef SandboxをVagrant+BerkShelfでさくっと作る
ども、大瀧です。
社内でそこかしこから"Chefで〜"、"Chefが〜"と聞こえるようになってきました。来月、Chefについてお話しする機会なんてのも巡ってきたので、日頃からChefを触っておかねばと一念発起しました!
が、Chefの環境作るのって結構面倒なんですよね。そこで、最近EC2に対応したVagrantを使ってChefのお勉強環境(Sandbox)をさくっと作ってみます。例によって、説明はいっぱい書いてありますが、かいつまんで目を通して、ところどころのコマンドを実行していく感じで見ていただくのがいいと思います。
使ってみたツール
- Chef Solo : Chefの実行方法はyamatoさんの記事にあるChef Server & Clientもありますが、今回はCookbookの勉強が目的なので、より簡単に構築できるChef Soloで行きます。
- Berkshelf : ChefのCookbook管理ソフトウェア。Ruby(gems)のBundler、PHPのComposerと言った、LLのライブラリ管理ソフトウェアと同じ発想で、数あるChef Cookbookをうまーくコーディネートしてくれる(らしい)仕組みです。Chefの実行に必須というわけではありませんが、公開されているCookbookの賢いインポートができるので、Cookbookの写経、勉強するのに便利です。
- Vagrant : 元はSun(現ORACLE)の仮想化ソフトウェア、Virtual Boxの仮想マシンを管理するためのツール。バージョン1.1でEC2&VPCに対応しました。Chef Soloとの連携機能があるので、1つの設定ファイルからEC2インスタンスの作成、起動とChef Soloの実行をコマンド一発で行えます。
1. AMI(EC2)のセットアップ
Chef Soloのインストール
まずは、Chef Solo(=Client)がインストール済みのAMIを準備します。今回はAmazon Linuxを使うので、公式のAMIからインスタンスを起動、SSH接続でec2-userでログインしChef Soloをインストールします。
[ec2-user@ip-XXX-XXX-XXX-XXX ~]$ curl -L https://www.opscode.com/chef/install.sh | sudo bash % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 6471 100 6471 0 0 7930 0 --:--:-- --:--:-- --:--:-- 10337 Downloading Chef for el... Installing Chef warning: /tmp/tmp.iHulWn0G/chef-.x86_64.rpm: Header V4 DSA/SHA1 Signature, key ID 83ef826a: NOKEY Preparing... ########################################### [100%] 1:chef ########################################### [100%] Thank you for installing Chef! [ec2-user@ip-XXX-XXX-XXX-XXX ~]$ chef-solo -v Chef: 11.4.0 [ec2-user@ip-XXX-XXX-XXX-XXX ~]$
sudoの設定変更
Amazon Linuxの初期設定では、Vagrantからsudoコマンドを実行できないようになっていますが、Chef Soloを実行するために必要です。あらかじめsudoの設定をvisudoコマンドで変更します。
[ec2-user@ip-XXX-XXX-XXX-XXX ~]$ sudo visudo Defaults requiretty ↓ #Defaults requiretty
AMIの作成
セットアップしたEC2からAMIを作成します。
2. Berkshelfのセットアップ
Berkshelfは、Vagrantを実行するPCにgemコマンドでインストールします。gemコマンドは、Rubyのライブラリ管理を行うRubyGemsに含まれるため、あらかじめRubyおよびRubyGemsをセットアップしておく必要があります。RubyGemsのインストールは、今回は割愛します。
vagrant_machine:~ $ sudo gem install berkshelf --no-ri --no-rdoc Fetching: berkshelf-1.4.0.gem (100%) Successfully installed berkshelf-1.4.0 1 gem installed vagrant_machine:~ $
※ Berkshelfに依存するいくつかのgemがインストールされる場合もあります。rbenv環境の場合は、rbenv rehashの実行を忘れずに!
Berkshelfは、berksコマンドで動作します。
vagrant_machine:~ $ berks -v Berkshelf (1.4.0) Author:: Jamie Winsor (<reset@riotgames.com>) Author:: Josiah Kiehl (<jkiehl@riotgames.com>) Author:: Michael Ivey (<michael.ivey@riotgames.com>) Author:: Justin Campbell (<justin.campbell@riotgames.com>) Copyright 2012 Riot Games :
3. Vagrantのセットアップ
Vagrantのインストールは、以前はgemコマンドでしたが最近のバージョンではインストーラをダウンロード、実行します。今回は現時点で最新のバージョン1.2.1を使用します。OSX Mountain Lionで動作確認していますが、Windows版、Linux版もあります。
Vagrantをインストールすると、vagrantコマンドを実行できるようになります。続いて、VagrantでEC2を管理するためにvagrant-awsプラグイン、berkshelfのCookbookをVagrantで読み込むためのvagrant-berkshelfプラグインをインストールします。
vagrant_machine:~ $ vagrant plugin install vagrant-aws Installing the 'vagrant-aws' plugin. This can take a few minutes... Installed the plugin 'vagrant-aws (0.2.2)'! vagrant_machine:~ $ vagrant plugin install vagrant-berkshelf Installing the 'vagrant-berkshelf' plugin. This can take a few minutes... Installed the plugin 'vagrant-berkshelf (1.2.0)'! vagrant_machine:~ $ vagrant plugin list vagrant-aws (0.2.2) vagrant-berkshelf (1.2.0) vagrant_machine:~ $
Vagrantでは、管理する仮想マシン(今回はEC2インスタンス)のひな形をBoxとして管理します。EC2インスタンスの場合は、AMIをベースにするため、EC2用の空のBox(dummy)を使用します。ここで、dummy boxをインポートしておきます。既にdummy boxをインポート済みの場合は、他の適当なbox名で構いません。
vagrant_machine:~ $ vagrant box add dummy https://github.com/mitchellh/vagrant-aws/raw/master/dummy.box Downloading or copying the box... Extracting box...e: 0/s, Estimated time remaining: --:--:--) Successfully added box 'dummy' with provider 'aws'!
Chef環境構築を一発実行!
材料がそろったので、1.のAMIをベースにBerkShelfでCookbookを選択、VagrantでEC2インスタンスを立ち上げ、Chef Soloを適用します。
Cookbook & Vagrantのひな形を作成
berksコマンドでCookbookのひな形を作成します。
vagrant_machine:~ $ berks cookbook sample-berkshelf create sample-berkshelf/files/default create sample-berkshelf/templates/default create sample-berkshelf/attributes create sample-berkshelf/definitions create sample-berkshelf/libraries create sample-berkshelf/providers create sample-berkshelf/recipes create sample-berkshelf/resources create sample-berkshelf/recipes/default.rb create sample-berkshelf/metadata.rb create sample-berkshelf/LICENSE create sample-berkshelf/README.md create sample-berkshelf/Berksfile create sample-berkshelf/chefignore create sample-berkshelf/.gitignore run git init from "./sample-berkshelf" create sample-berkshelf/Gemfile create sample-berkshelf/Vagrantfile Using sample-berkshelf (0.1.0) at path: '/Users/XXXXXX/sample-berkshelf'
Cookbook名(今回はsample-berkshelf)のディレクトリが作成され、いくつかのひな形ファイルが作成されます。
今回の構成でいじるファイルをピックアップします。
- Berksfile : Berkshelfの構成ファイル。ロードしたいCookbookを定義します。
- Vagrantfile : Vagrantの構成ファイル。vagrantコマンドで作成することもできますが、Berkshelf向けの設定が入っているので、このあとEC2向けに修正・追加します。
Cookbookの作成、選択
EC2に適用するChefのCookbookを用意します。berksコマンドでひな形は作成済みなので、自前のRecipeを追加する感じです。また、Berksfileファイルに既存のCookbookを記述することで、Cookbookのインポートを行うこともできます。今回は、Opscodeのnginx Cookbookをインポートしてみます。
vagrant_machine:~ $ cd sample-berkshelf vagrant_machine:~ $ vi Berksfile site :opscode metadata cookbook 'nginx'
Cookbookのインポートは、RubyのBundlerと同様にberksコマンドを実行します。 BerkshelfでインポートしたCookbookは、~/.berkshelf/cookbooks/以下に配置されます。
vagrant_machine:~ $ berks Installing nginx (1.4.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing bluepill (2.2.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing rsyslog (1.5.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing runit (0.16.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing build-essential (1.4.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing yum (2.2.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing apt (1.9.2) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' Installing ohai (1.1.8) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks' vagrant_machine:~ $ ls ~/.berkshelf/cookbooks/ apt-1.9.2/ build-essential-1.4.0/ ohai-1.1.8/ runit-0.16.2/ bluepill-2.2.2/ nginx-1.4.0/ rsyslog-1.5.0/ yum-2.2.0/
Vagrantfileの修正
Vagrantで管理するEC2インスタンスの設定を、Vagrantfileファイルに記述します。以下2点を修正します。
- BerkshelfによるVirtualBox向けの設定が既にあるので、EC2用に書き換える
- インスタンスに適用するChef Soloレシピを指定する
Vagrantバージョン1.2で、EC2インスタンスに接続するときのSSH構成の書き方が変わりました。バージョン1.1までの書き方では、vagrant sshコマンドがエラーになるので、注意してください。
vagrant_machine:~ $ vi Vagrantfile
項目が多かったので、diffの結果を貼付けます。
vagrant_machine:~ $ diff -u Vagrantfile.org Vagrantfile --- Vagrantfile.org 2013-04-24 08:01:19.000000000 +0900 +++ Vagrantfile 2013-04-24 08:13:56.000000000 +0900 @@ -6,20 +6,20 @@ # options are documented and commented below. For a complete reference, # please see the online documentation at vagrantup.com. - config.vm.hostname = "sample-berkshelf-berkshelf" + #config.vm.hostname = "sample-berkshelf-berkshelf" # Every Vagrant virtual environment requires a box to build off of. - config.vm.box = "Berkshelf-CentOS-6.3-x86_64-minimal" + config.vm.box = "dummy" # The url from where the 'config.vm.box' box will be fetched if it # doesn't already exist on the user's system. - config.vm.box_url = "https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box" + #config.vm.box_url = "https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box" # Assign this VM to a host-only network IP, allowing you to access it # via the IP. Host-only networks can talk to the host machine as well as # any other machines on the same network, but cannot be accessed (through this # network interface) by any external networks. - config.vm.network :private_network, ip: "33.33.33.10" + #config.vm.network :private_network, ip: "33.33.33.10" # Create a public network, which generally matched to bridged network. # Bridged networks make the machine appear as another physical device on @@ -71,16 +71,28 @@ # config.berkshelf.except = [] config.vm.provision :chef_solo do |chef| - chef.json = { - :mysql => { - :server_root_password => 'rootpass', - :server_debian_password => 'debpass', - :server_repl_password => 'replpass' - } - } + # chef.json = { + # :mysql => { + # :server_root_password => 'rootpass', + # :server_debian_password => 'debpass', + # :server_repl_password => 'replpass' + # } + # } chef.run_list = [ - "recipe[sample-berkshelf::default]" + "recipe[nginx]" ] end + config.vm.provider :aws do |aws, override| + aws.access_key_id = "<AWS_ACCESS_KEY>" + aws.secret_access_key = "<AWS_SECRET_ACCESS_KEY>" + aws.keypair_name = "<KeyPair>" + aws.instance_type = "t1.micro" + aws.region = "ap-northeast-1" + aws.ami = "ami-XXXXXXXX" + aws.security_groups = [ '<Security_Group>' ] + + override.ssh.username = "ec2-user" + override.ssh.private_key_path = "<Your_SSH_Private_Key>.pem" + end end vagrant_machine:~ $
インスタンスの作成、起動、Chef Soloの実行
準備ができたら、いよいよインスタンス作成&起動です。vagrant upコマンドの実行で、AMIからのEC2インスタンス作成、起動、Chef Soloの実行まで一気にやってくれます。うまくいけば結構感動モノです。
vagrant_machine:~ $ vagrant up --provider=aws Bringing machine 'default' up with 'aws' provider... [Berkshelf] Updating Vagrant's berkshelf: '/Users/XXXXXX/.berkshelf/vagrant/berkshelf-20130424-2472-weucfz' [Berkshelf] Using sample-berkshelf (0.1.0) at path: '/Users/XXXXXX/Vagrants/sample-berkshelf' [Berkshelf] Using nginx (1.4.0) [Berkshelf] Using bluepill (2.2.2) [Berkshelf] Using rsyslog (1.5.0) [Berkshelf] Using runit (0.16.2) [Berkshelf] Using build-essential (1.4.0) [Berkshelf] Using yum (2.2.0) [Berkshelf] Using apt (1.9.2) [Berkshelf] Using ohai (1.1.8) [default] Warning! The AWS provider doesn't support any of the Vagrant high-level network configurations (`config.vm.network`). They will be silently ignored. [default] Launching an instance with the following settings... [default] -- Type: t1.micro [default] -- AMI: ami-XXXXXXXX [default] -- Region: ap-northeast-1 [default] -- Keypair: XXXXXX [default] -- Security Groups: ["XXXXXX"] [default] Waiting for instance to become "ready"... [default] Waiting for SSH to become available... [default] Machine is booted and ready for use! [default] Rsyncing folder: /Users/XXXXXX/Vagrants/sample-berkshelf/ => /vagrant [default] Rsyncing folder: /Users/XXXXXX/.berkshelf/vagrant/berkshelf-20130424-2472-weucfz/ => /tmp/vagrant-chef-1/chef-solo-1/cookbooks [default] Running provisioner: chef_solo... Generating chef JSON and uploading... Running chef-solo... [2013-04-24T04:58:43+00:00] INFO: *** Chef 11.4.4 *** [2013-04-24T04:58:46+00:00] INFO: Setting the run_list to ["recipe[nginx]"] from JSON [2013-04-24T04:58:46+00:00] INFO: Run List is [recipe[nginx]] [2013-04-24T04:58:46+00:00] INFO: Run List expands to [nginx] [2013-04-24T04:58:46+00:00] INFO: Starting Chef Run for ip-10-130-91-13.ap-southeast-1.compute.internal [2013-04-24T04:58:46+00:00] INFO: Running start handlers [2013-04-24T04:58:46+00:00] INFO: Start handlers complete. : (以下、Chef Soloの実行結果がつづく) vagrant_machine:~ $
EC2インスタンスへのSSH接続は、vagrant sshコマンドでいけます。Opscodeのnginx Recipeは、Nginxのインストールと設定ファイルの配置を行うようなので、EC2インスタンスに構成済みかどうか、それぞれ確認してみます。
vagrant_machine:~ $ vagrant ssh Last login: Wed Apr 24 04:47:23 2013 from XXXXXXXXXXXXX __| __|_ ) _| ( / Amazon Linux AMI ___|\___|___| https://aws.amazon.com/amazon-linux-ami/2013.03-release-notes/ There are 10 security update(s) out of 17 total update(s) available Run "sudo yum update" to apply all updates. [ec2-user@ip-XXX-XXX-XXX-XXX ~]$ rpm -q nginx nginx-1.2.7-2.8.amzn1.x86_64 [ec2-user@ip-XXX-XXX-XXX-XXX ~]$ ls /etc/nginx/ conf.d fastcgi.conf.default fastcgi_params.default koi-win mime.types.default nginx.conf.default scgi_params.default sites-enabled uwsgi_params.default fastcgi.conf fastcgi_params koi-utf mime.types nginx.conf scgi_params sites-available uwsgi_params win-utf [ec2-user@ip-XXX-XXX-XXX-XXX ~]$ exit vagrant_machine:~ $
ちゃんと入ってますね。
Cookbookを追加した、Recipeをいじった、というときはvagrant provisionコマンドでChef Soloを再実行できます。Recipeで試行錯誤するときにはvagrant provisionとvagrant sshがメインになると思います。
後片付け
一通りいじって"疲れた"とか"飽きてきた"ときには、EC2インスタンスを削除(Terminate)しちゃいましょう。これもvagrant destroyコマンドで一発です。
vagrant_machine:~ $ vagrant destroy [default] Terminating the instance...
Vagrantには、vagrant haltという仮想マシンをシャットダウンするコマンドもあるのですが、現状EC2インスタンスでは動きません。Chefの実験環境で使う分には、手元にCookbookも残りますし、インスタンスをTerminateする運用でさほど困らないのでは、と思います。
まとめ
今回はChefの実験環境としてCookbookを管理するBerkshelfと、EC2インスタンスを管理するVagrantを組み合わせて使ってみました。
ちょっと欲張っていろんなツールを引っ張ってきましたが、Chefの実験環境としてはまずまずのものになっているのではないでしょうか。みなさんのChef力向上の一歩になると幸いです。